package com.questionnaires.repository;


import org.hibernate.SessionFactory;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import com.questionnaires.model.Category;
import com.questionnaires.exception.NotExistsException;
import com.questionnaires.exception.NotUniqueException;

/**
 * @author rominamilea@gmail.com
 */

@Repository(value = "categoryRepository")
public class CategoryRepositoryImpl implements CategoryRepository {

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * {@inheritDoc}
     */
    @Transactional
    public void saveOrUpdate(Category category) throws NotUniqueException {
        if (findByName(category.getName()) != null) {
            throw new NotUniqueException("Category with name " + category.getName() + " already exists.");
        }
        sessionFactory.getCurrentSession().saveOrUpdate(category);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional
    public void delete(long id) throws NotExistsException {
        Category category = (Category) findById(id);
        if (category == null) {
            throw new NotExistsException("Category with id = " + id + " does not exists.");
        }
        sessionFactory.getCurrentSession().delete(category);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional
    public List<Category> getCategories() {
        return (List<Category>) sessionFactory.getCurrentSession().createQuery("from Category").list();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    private Category findByName(String name) {
        Query query = sessionFactory.getCurrentSession().createQuery("from Category category where category.name =:name");
        query.setString("name", name);
        if (query.list().isEmpty()) {
            return null;
        }
        return (Category) query.list().get(0);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    private Category findById(long id) {
        return (Category) sessionFactory.getCurrentSession().get(Category.class, id);
    }
}
